//
//  NativeDropboxLoginExtensioniOS.m
//  NativeDropboxLoginExtensioniOS
//
//  Created by Radoslava Leseva on 19/05/2012. www.diadraw.com, www.ideadrawapp.com
//  Copyright (c) 2012 DiaDraw. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <DropboxSDK/DropboxSDK.h>
#import "NativeDropboxLoginExtensioniOS.h"
#import "UIViewController+Orientation.h"

@interface NativeDropboxLoginExtensioniOS () <DBSessionDelegate, DBNetworkRequestDelegate>

@end



@implementation NativeDropboxLoginExtensioniOS


typedef enum ARGS
{
    ARG_APP_KEY = 0,
    ARG_APP_SECRET = 1,
    ARG_APP_ROOT = 2,

    ARG_COUNT_MAX

} ARG_INDEX;


FREContext g_ctx;

NativeDropboxLoginExtensioniOS *loginHelper;

static NSString *event_name = @"DROPBOX_EXT_EVENT";



- (id)init
{
    self = [super init];
    
    if (self) 
    {
        
    }
    
    return self;
}


-(void) linkWithDropbox: (NSString *) appKey
              appSecret: (NSString *) appSecret
                   root: (NSString *) root
{
    NSString* errorMsg = nil;
	if ([appKey rangeOfCharacterFromSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]].location != NSNotFound) 
    {
        errorMsg = @"App key error: ";
	} 
    
    else if ([appSecret rangeOfCharacterFromSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]].location != NSNotFound) 
    {
        errorMsg = @"App secret error: ";
	} 
    
    else if ([root length] == 0) 
    {
        errorMsg =  @"Dropbox root error: ";
	} 
    
    else 
    {
		NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
		NSData *plistData = [NSData dataWithContentsOfFile:plistPath];
		NSDictionary *loadedPlist = 
        [NSPropertyListSerialization 
         propertyListFromData:plistData mutabilityOption:0 format:NULL errorDescription:NULL];
		NSString *scheme = [[[[loadedPlist objectForKey:@"CFBundleURLTypes"] objectAtIndex:0] objectForKey:@"CFBundleURLSchemes"] objectAtIndex:0];
		
        if ([scheme isEqual:@"db-APP_KEY"]) 
        {
            errorMsg = @"URL scheme error";
		}
	}
    
    
    DBSession* session = [ [ DBSession alloc ] initWithAppKey:appKey appSecret:appSecret root:root ];
    session.delegate = self;
    [ DBSession setSharedSession:session ];
    [ session release ];
    
    [ DBRequest setNetworkRequestDelegate:self ];
    
    if (errorMsg != nil) {
		[[[[UIAlertView alloc]
		   initWithTitle:@"Error Configuring Session" message:errorMsg 
		   delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]
		  autorelease]
		 show];
	}
    
    if ( [ [ DBSession sharedSession ] isLinked ] )
    {
        FREDispatchStatusEventAsync(g_ctx, (uint8_t*)[ event_name UTF8String ], (uint8_t*)[ @"DROPBOX_EXT_LINKED" UTF8String ]);
    }    
    else 
    {
        [self performLink];
    }
}


- (void) performLink
{
    if ( ![[ DBSession sharedSession ] isLinked ] )
    {
        [ [ DBSession sharedSession ] linkFromController:[[[UIApplication sharedApplication] keyWindow] rootViewController]];
    }
}


- (void) performUnlink
{
    [ [ DBSession sharedSession ] unlinkAll ];
    
    FREDispatchStatusEventAsync(g_ctx, (uint8_t*)[ event_name UTF8String ], (uint8_t*)[ @"DROPBOX_EXT_UNLINKED" UTF8String ]);
    
    [[[[UIAlertView alloc] 
       initWithTitle:@"Account Unlinked!" message:@"Your dropbox account has been unlinked" 
       delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]
      autorelease]
     show];    
}


#pragma mark -
#pragma mark DBSessionDelegate methods

- (void)sessionDidReceiveAuthorizationFailure:(DBSession*)session userId:(NSString *)userId {
	relinkUserId = [userId retain];
	[[[[UIAlertView alloc] 
	   initWithTitle:@"Dropbox Session Ended" message:@"Do you want to relink?" delegate:self 
	   cancelButtonTitle:@"Cancel" otherButtonTitles:@"Relink", nil]
	  autorelease]
	 show];
}


#pragma mark -
#pragma mark DBNetworkRequestDelegate methods

static int outstandingRequests;

- (void)networkRequestStarted {
	outstandingRequests++;
	if (outstandingRequests == 1) {
		[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
	}
}

- (void)networkRequestStopped {
	outstandingRequests--;
	if (outstandingRequests == 0) {
		[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
	}
}



NSString * getNSStringFromCString( FREObject arg )
{
    NSString * resultString = NULL;
    
    uint32_t strLength = 0;
    const uint8_t * argCString = NULL;
    FREResult argumentResult = FREGetObjectAsUTF8( arg, &strLength, &argCString );
    
    if ( ( FRE_OK == argumentResult ) && ( 0 < strLength ) && ( NULL != argCString ) )
    {
        resultString = [ NSString stringWithUTF8String:(const char *) argCString ];
    }
    
    return resultString;
}



FREObject ActionSCriptUnlinkFromDropbox( FREContext ctx, void* funcData, uint32_t argc, FREObject argv[] )
{
    if ( NULL == loginHelper )
    {
        loginHelper = [ [ NativeDropboxLoginExtensioniOS alloc ] init ];
    }
    
    [ loginHelper performUnlink ];

    return NULL;
}


FREObject ActionSCriptLinkWithDropbox( FREContext ctx, void* funcData, uint32_t argc, FREObject argv[] )
{
    // Extract the log-in parameters:
    NSString * appKey          = ( ARG_APP_KEY < argc )     ? getNSStringFromCString( argv[ ARG_APP_KEY ] )     : NULL;
    NSString * appSecret       = ( ARG_APP_SECRET < argc )  ? getNSStringFromCString( argv[ ARG_APP_SECRET ] )  : NULL;
    NSString * appRoot         = ( ARG_APP_ROOT < argc )    ? getNSStringFromCString( argv[ ARG_APP_ROOT ] )    : NULL;
    
    
    if ( NULL == loginHelper )
    {
        loginHelper = [ [ NativeDropboxLoginExtensioniOS alloc ] init ];
    }
    
    [ loginHelper linkWithDropbox:appKey appSecret:appSecret root:appRoot];
    
    return NULL;
}


// Context and Extension Initialization and Finalization
void DropboxLoginContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx, 
                                      uint32_t* numFunctionsToSet, const FRENamedFunction** functionsToSet) 
{
    static FRENamedFunction extensionFunctions[] =
    {
        { (const uint8_t*) "as_linkWithDropbox", NULL, &ActionSCriptLinkWithDropbox },
        { (const uint8_t*) "as_unlinkFromDropbox", NULL, &ActionSCriptUnlinkFromDropbox }
    };
    
    *numFunctionsToSet = sizeof( extensionFunctions ) / sizeof( FRENamedFunction );
    *functionsToSet = extensionFunctions;
	
	g_ctx = ctx;
}


void DropboxLoginContextFinalizer(FREContext ctx) 
{
    return;
}


void DropboxLoginExtensionInitializer(void** extDataToSet, 
                               FREContextInitializer* ctxInitializerToSet, 
                               FREContextFinalizer* ctxFinalizerToSet) 
{
    *extDataToSet = NULL;
    *ctxInitializerToSet = &DropboxLoginContextInitializer;
    *ctxFinalizerToSet = &DropboxLoginContextFinalizer;
}


void DropboxLoginExtensionFinalizer(void* extData) 
{    
    return;
}


@end
